<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<!-- HTML file produced from file: manual.tex --
 -- using Hyperlatex v 2.3.1 (c) Otfried Cheong--
 -- on Emacs 21.4 (patch 12) "Portable Code" XEmacs Lucid, Wed Jun  2 18:56:58 2004 -->
<HEAD>
<TITLE>Scheme 48 Manual -- Records</TITLE>

</HEAD><BODY BGCOLOR="#ffffff">
<EM>Scheme 48 Manual</EM> | <A HREF="s48manual.html#top_node">Contents</A> | In Chapter: <A HREF="s48manual_35.html">Libraries</A><BR>Previous: <A HREF="s48manual_44.html">Arrays</A> | Next: <A HREF="s48manual_46.html">Finite record types</A>
<H2>Records</H2>

<P>New types can be constructed using the <CODE>define-record-type</CODE> macro
 from the <CODE>define-record-types</CODE> structure
The general syntax is:
<BLOCKQUOTE><PRE>
(define-record-type <CODE><I>tag</I></CODE> <CODE><I>type-name</I></CODE>
  (<CODE><I>constructor-name</I></CODE> <CODE><I>field-tag</I></CODE> ...)
  <CODE><I>predicate-name</I></CODE>
  (<CODE><I>field-tag</I></CODE> <CODE><I>accessor-name</I></CODE> [<CODE><I>modifier-name</I></CODE>])
  ...)
</PRE></BLOCKQUOTE>
This makes the following definitions:
<UL><LI><table border=0 cellspacing=0 cellpadding=0 width=80%>
<tr> <td><CODE><CODE><I>type-name</I></CODE></CODE></td> <td align=right>type</td></tr></table>
<LI><CODE>(<CODE><I>constructor-name</I></CODE><I>&nbsp;field-init&nbsp;...</I>)&nbsp;-&gt;&nbsp;<I>type-name</I></CODE>
<LI><CODE>(<CODE><I>predicate-name</I></CODE><I>&nbsp;value</I>)&nbsp;-&gt;&nbsp;<I>boolean</I></CODE>
<LI><CODE>(<CODE><I>accessor-name</I></CODE><I>&nbsp;type-name</I>)&nbsp;-&gt;&nbsp;<I>value</I></CODE>
<LI><CODE>(<CODE><I>modifier-name</I></CODE><I>&nbsp;type-name&nbsp;value</I>)</CODE>
</UL>
<CODE><I>Type-name</I></CODE> is the record type itself, and can be used to
 specify a print method (see below).
<CODE><I>Constructor-name</I></CODE> is a constructor that accepts values
 for the fields whose tags are specified.
<CODE><I>Predicate-name</I></CODE> is a predicate that returns <CODE>#t</CODE> for
 elements of the type and <CODE>#f</CODE> for everything else.
The <CODE><I>accessor-name</I></CODE>s retrieve the values of fields,
 and the <CODE><I>modifier-name</I></CODE>'s update them.
<CODE><I>Tag</I></CODE> is used in printing instances of the record type and
 the <CODE><I>field-tag</I></CODE>s are used in the inspector and to match
 constructor arguments with fields.
<P><UL><LI><CODE>(define-record-discloser<I>&nbsp;type&nbsp;discloser</I>)</CODE><A NAME="1">&nbsp;</A>
</UL>
<CODE>Define-record-discloser</CODE> determines how
 records of type <CODE><I>type</I></CODE> are printed.
<CODE><I>Discloser</I></CODE> should be procedure which takes a single
 record of type <CODE><I>type</I></CODE> and returns a list whose car is
 a symbol.
The record will be printed as the value returned by <CODE><I>discloser</I></CODE>
 with curly braces used instead of the usual parenthesis.
<P>For example
<BLOCKQUOTE><PRE>
(define-record-type pare :pare
  (kons x y)
  pare?
  (x kar set-kar!)
  (y kdr))
</PRE></BLOCKQUOTE>
defines <CODE>kons</CODE> to be a constructor, <CODE>kar</CODE> and <CODE>kdr</CODE> to be
 accessors, <CODE>set-kar!</CODE> to be a modifier, and <CODE>pare?</CODE> to be a predicate
 for a new type of object.
The type itself is named <CODE>:pare</CODE>.
<CODE>Pare</CODE> is a tag used in printing the new objects.
<P>By default, the new objects print as <CODE>#{Pare}</CODE>.
The print method can be modified using <CODE>define-record-discloser</CODE>:
<BLOCKQUOTE><PRE>
(define-record-discloser :pare
  (lambda (p) `(pare ,(kar p) ,(kdr p))))
</PRE></BLOCKQUOTE>
will cause the result of <CODE>(kons 1 2)</CODE> to print as
 <CODE>#{Pare 1 2}</CODE>.
<P><A HREF="s48manual_74.html#3"><CODE>Define-record-resumer</CODE></A>
 can be used to control how records are stored in heap images.
<P><H3><A NAME="2">Low-level access to records</A></H3>
<P>Records are implemented using primitive objects exactly analogous
 to vectors.
Every record has a record type (which is another record) in the first slot.
Note that use of these procedures, especially <CODE>record-set!</CODE>, breaks
 the record abstraction described above; caution is advised.
<P>These procedures are in the structure <CODE>records</CODE>.
<P><UL><LI><CODE>(make-record<I>&nbsp;n&nbsp;value</I>)&nbsp;-&gt;&nbsp;<I>record</I></CODE><A NAME="3">&nbsp;</A>
<LI><CODE>(record<I>&nbsp;value&nbsp;...</I>)&nbsp;-&gt;&nbsp;<I>record-vector</I></CODE><A NAME="4">&nbsp;</A>
<LI><CODE>(record?<I>&nbsp;value</I>)&nbsp;-&gt;&nbsp;<I>boolean</I></CODE><A NAME="5">&nbsp;</A>
<LI><CODE>(record-length<I>&nbsp;record</I>)&nbsp;-&gt;&nbsp;<I>integer</I></CODE><A NAME="6">&nbsp;</A>
<LI><CODE>(record-type<I>&nbsp;record</I>)&nbsp;-&gt;&nbsp;<I>value</I></CODE><A NAME="7">&nbsp;</A>
<LI><CODE>(record-ref<I>&nbsp;record&nbsp;i</I>)&nbsp;-&gt;&nbsp;<I>value</I></CODE><A NAME="8">&nbsp;</A>
<LI><CODE>(record-set!<I>&nbsp;record&nbsp;i&nbsp;value</I>)</CODE><A NAME="9">&nbsp;</A>
</UL>
These the same as the standard <CODE>vector-</CODE> procedures except that they
 operate on records.
The value returned by <CODE>record-length</CODE> includes the slot holding the
 record's type.
<CODE>(record-type <CODE><I>x</I></CODE>)</CODE> is equivalent to <CODE>(record-ref <CODE><I>x</I></CODE> 0)</CODE>.
<P><H3><A NAME="10">Record types</A></H3>
<P>Record types are themselves records of a particular type (the first slot
 of <CODE>:record-type</CODE> points to itself).
A record type contains four values: the name of the record type, a list of
 the names its fields, and procedures for disclosing and resuming records
 of that type.
Procedures for manipulating them are in the structure <CODE>record-types</CODE>.
<P><UL><LI><CODE>(make-record-type<I>&nbsp;name&nbsp;field-names</I>)&nbsp;-&gt;&nbsp;<I>record-type</I></CODE><A NAME="11">&nbsp;</A>
<LI><CODE>(record-type?<I>&nbsp;value</I>)&nbsp;-&gt;&nbsp;<I>boolean</I></CODE><A NAME="12">&nbsp;</A>
<LI><CODE>(record-type-name<I>&nbsp;record-type</I>)&nbsp;-&gt;&nbsp;<I>symbol</I></CODE><A NAME="13">&nbsp;</A>
<LI><CODE>(record-type-field-names<I>&nbsp;record-type</I>)&nbsp;-&gt;&nbsp;<I>symbols</I></CODE><A NAME="14">&nbsp;</A>
</UL>
<P><UL><LI><CODE>(record-constructor<I>&nbsp;record-type&nbsp;field-names</I>)&nbsp;-&gt;&nbsp;<I>procedure</I></CODE><A NAME="15">&nbsp;</A>
<LI><CODE>(record-predicate<I>&nbsp;record-type</I>)&nbsp;-&gt;&nbsp;<I>procedure</I></CODE><A NAME="16">&nbsp;</A>
<LI><CODE>(record-accessor<I>&nbsp;record-type&nbsp;field-name</I>)&nbsp;-&gt;&nbsp;<I>procedure</I></CODE><A NAME="17">&nbsp;</A>
<LI><CODE>(record-modifier<I>&nbsp;record-type&nbsp;field-name</I>)&nbsp;-&gt;&nbsp;<I>procedure</I></CODE><A NAME="18">&nbsp;</A>
</UL>
These procedures construct the usual record-manipulating procedures.
<CODE>Record-constructor</CODE> returns a constructor that is passed the initial
 values for the fields specified and returns a new record.
<CODE>Record-predicate</CODE> returns a predicate that return true when passed
 a record of type <CODE><I>record-type</I></CODE> and false otherwise.
<CODE>Record-accessor</CODE> and <CODE>record-modifier</CODE> return procedures that
 reference and set the given field in records of the approriate type.
<P><UL><LI><CODE>(define-record-discloser<I>&nbsp;record-type&nbsp;discloser</I>)</CODE><A NAME="19">&nbsp;</A>
<LI><CODE>(define-record-resumer<I>&nbsp;record-type&nbsp;resumer</I>)</CODE><A NAME="20">&nbsp;</A>
</UL>
<CODE>Record-types</CODE> is the initial exporter of
 <CODE>define-record-discloser</CODE>
 (re-exported by <CODE>define-record-types</CODE> described above)
 and
 <CODE>define-record-resumer</CODE>
 (re-exported by
 <A HREF="s48manual_74.html#3"><CODE>external-calls</CODE></A>).
<P>The procedures described in this section can be used to define new
 record-type-defining macros.
<BLOCKQUOTE><PRE>
(define-record-type pare :pare
  (kons x y)
  pare?
  (x kar set-kar!)
  (y kdr))
</PRE></BLOCKQUOTE>
is (sematically) equivalent to
<BLOCKQUOTE><PRE>
(define :pare (make-record-type 'pare '(x y)))
(define kons (record-constructor :pare '(x y)))
(define kar (record-accessor :pare 'x))
(define set-kar! (record-modifier :pare 'x))
(define kdr (record-accessor :pare 'y))
</PRE></BLOCKQUOTE>
<P>The "(semantically)" above is because <CODE>define-record-type</CODE> adds
 declarations, which allows the type checker to detect some misuses of records,
 and uses more efficient definitions for the constructor, accessors, and
 modifiers.
Ignoring the declarations, which will have to wait for another edition of
 the manual, what the above example actually expands into is:
<BLOCKQUOTE><PRE>
(define :pare (make-record-type 'pare '(x y)))
(define (kons x y) (record :pare x y))
(define (kar r) (checked-record-ref r :pare 1))
(define (set-kar! r new)
  (checked-record-set! r :pare 1 new))
(define (kdr r) (checked-record-ref r :pare 2))
</PRE></BLOCKQUOTE>
<CODE>Checked-record-ref</CODE> and <CODE>Checked-record-set!</CODE> are
 low-level procedures that check the type of the
 record and access or modify it using a single VM instruction.
<P><P>
  
Previous: <A HREF="s48manual_44.html">Arrays</A> | Next: <A HREF="s48manual_46.html">Finite record types</A></BODY></HTML>
